﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using TestPrint.PrintNameHelp;
using TestPrint.XMLhelp;

namespace TestPrint.CommonPrintSet
{
    public class LocalSettings<TLocalSetting>
    {
        public static string ConfigPath = AppDomain.CurrentDomain.BaseDirectory + @"Config\LocalSettings.json";

        public static Dictionary<string, object> dict { get; set; }
        static LocalSettings()
        {
            try
            {
                dict = JsonHelper.DeserializeObject<Dictionary<string, object>>(File.ReadAllText(ConfigPath));
            }
            catch
            {
                dict = new Dictionary<string, object>();
            }
            SettingList = new List<TreeItem>();

            Type mainType = typeof(TLocalSetting);
            Type requestType = typeof(TreeItem);
            FieldInfo[] fields = mainType.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
            foreach (FieldInfo info in fields)
            {
                if (requestType.IsAssignableFrom(info.FieldType))
                {
                    var item = (TreeItem)info.GetValue(mainType);
                    SettingList.Add(item);
                }
            }
        }
        public static List<TreeItem> SettingList
        {
            get; set;
        }

        /// <summary>
        /// 通过键查找配置
        /// </summary>
        /// <returns>T</returns>
        public static T GetObject<T>(ControlTreeItem<T> settingItem) where T : new()
        {
            if (!dict.ContainsKey(settingItem.Key)) return new T();
            var obj = dict[settingItem.Key];
            if (obj != null)
            {
                if (obj is T)
                {
                    return (T)obj;
                }
                var type = obj.GetType();
                switch (type.Name)
                {
                    case "JObject":
                        {
                            string value = obj.ToString();
                            var v = JsonHelper.DeserializeObject<T>(value);
                            dict[settingItem.Key] = v;
                            return v;
                        }
                    default:
                        return new T();
                }
            }
            return new T();
        }

        /// <summary>
        /// 打开配置窗体
        /// </summary>
        public static DialogResult ShowUI()
        {
            frmSettingManager frmSetting = new frmSettingManager(SettingList);
            return frmSetting.ShowDialog();
        }

        /// <summary>
        /// 根据指定项打开配置窗体控件
        /// </summary>
        public static T ShowUI<T>(ControlTreeItem<T> settingItem) where T : new()
        {
            frmSettingManager frmSetting = new frmSettingManager(settingItem.Key, SettingList);
            if (frmSetting.ShowDialog() == DialogResult.OK)
                return GetObject(settingItem);
            return default(T);
        }

        /// <summary>
        /// 验证配置并根据指定项打开配置窗体控件，通过判断返回对象是否为空验证是否设置成功。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="settingItem">TreeItem</param>
        /// <param name="check">验证方法</param>
        /// <returns></returns>
        public static T ShowUI<T>(ControlTreeItem<T> settingItem, Action<Context<T>> check) where T : new()
        {
            while (true)
            {
                if (check != null)
                {
                    var context = new Context<T> { Setting = GetObject(settingItem) };
                    check(context);
                    if (context.Errors.Count > 0)
                    {
                        frmSettingManager frmSetting = new frmSettingManager(settingItem.Key, SettingList);
                        frmSetting.TipMessage = string.Join("\r\n", context.Errors);
                        if (frmSetting.ShowDialog() != DialogResult.OK)
                            return default(T);
                    }
                    else
                        return context.Setting;
                }

            }
        }

        /// <summary>
        /// 设置配置
        /// </summary>
        /// <param name="Key">键</param>
        /// <param name="Value">值</param>
        public static void Save<T>(ControlTreeItem<T> settingItem, T Value)
        {
            dict[settingItem.Key] = Value;
            Save();
        }

        /// <summary>
        /// 保存配置
        /// </summary>
        public static void Save()
        {
            Directory.CreateDirectory(Path.GetDirectoryName(ConfigPath));
            File.WriteAllText(ConfigPath, JsonHelper.SerializeObject(dict));
        }
    }

    public class Context<T>
    {
        public T Setting { get; set; }
        public List<string> Errors = new List<string>();
    }
}
